package com.inspur.edp.bef.extendinfo.server.core;

import com.inspur.edp.bef.bemanager.gspbusinessentity.cache.GspBeExtendInfoCacheManager;
import com.inspur.edp.bef.bemanager.gspbusinessentity.repository.GspBeExtendInfoRepository;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.gspbusinessentity.entity.BeConfigCollectionInfo;
import com.inspur.edp.bef.bizentity.gspbusinessentity.entity.GspBeExtendInfo;
import com.inspur.edp.bef.bizentity.gspbusinessentity.entity.GspBeExtendInfoEntity;
import com.inspur.edp.bef.extendinfo.server.api.IGspBeExtendInfoRpcService;
import com.inspur.edp.cdp.common.utils.json.JsonUtil;
import io.swagger.util.Json;

import java.util.ArrayList;
import java.util.List;

public class GspBeExtendInfoRpcServiceImp implements IGspBeExtendInfoRpcService {
    private final GspBeExtendInfoCacheManager gspBeExtendInfoCacheManager;
    private final GspBeExtendInfoRepository repository;

    public GspBeExtendInfoRpcServiceImp(GspBeExtendInfoRepository repository, GspBeExtendInfoCacheManager gspBeExtendInfoCacheManager) {
        this.repository = repository;
        this.gspBeExtendInfoCacheManager = gspBeExtendInfoCacheManager;
        //重启应用时清空旧版缓存，防止数据库已更新但缓存未更新的情况
        this.gspBeExtendInfoCacheManager.clear();
    }

    @Override
    public GspBeExtendInfo getBeExtendInfo(String id) {
        if (id == null || id.length() == 0)
            return null;
        GspBeExtendInfo gspBeExtendInfoFromCache = gspBeExtendInfoCacheManager.get(id);
        if (gspBeExtendInfoFromCache != null) {
            return gspBeExtendInfoFromCache;
        }
        GspBeExtendInfoEntity beExtendInfoEntityFromRepo = repository.findById(id).orElse(null);
        if (beExtendInfoEntityFromRepo == null) {
            return null;
        }
        GspBeExtendInfo beExtendInfoFromRepo = getGspBeExtendInfo(beExtendInfoEntityFromRepo);
        gspBeExtendInfoCacheManager.put(id, beExtendInfoFromRepo);
        return beExtendInfoFromRepo;
    }

    private GspBeExtendInfo getGspBeExtendInfo(GspBeExtendInfoEntity gspBeExtendInfoEntity) {
        if (gspBeExtendInfoEntity == null)
            return null;
        GspBeExtendInfo gspBeExtendInfo = new GspBeExtendInfo();
        gspBeExtendInfo.setId(gspBeExtendInfoEntity.getId());
        gspBeExtendInfo.setConfigId(gspBeExtendInfoEntity.getConfigId());
        gspBeExtendInfo.setCreatedBy(gspBeExtendInfoEntity.getCreatedBy());
        gspBeExtendInfo.setCreatedOn(gspBeExtendInfoEntity.getCreatedOn());
        gspBeExtendInfo.setLastChangedBy(gspBeExtendInfoEntity.getLastChangedBy());
        gspBeExtendInfo.setLastChangedOn(gspBeExtendInfoEntity.getLastChangedOn());
        gspBeExtendInfo.setExtendInfo(gspBeExtendInfoEntity.getExtendInfo());
        gspBeExtendInfo.setBeConfigCollectionInfo(convertToBeConfigCollectionInfo(gspBeExtendInfoEntity.getBeConfigCollectionInfo()));
        return gspBeExtendInfo;
    }

    private GspBeExtendInfoEntity getGspBeExtendInfoEntity(GspBeExtendInfo gspBeExtendInfo) {
        if (gspBeExtendInfo == null)
            return null;
        GspBeExtendInfoEntity gspBeExtendInfoEntity = new GspBeExtendInfoEntity();
        gspBeExtendInfoEntity.setId(gspBeExtendInfo.getId());
        gspBeExtendInfoEntity.setConfigId(gspBeExtendInfo.getConfigId());
        gspBeExtendInfoEntity.setCreatedBy(gspBeExtendInfo.getCreatedBy());
        gspBeExtendInfoEntity.setCreatedOn(gspBeExtendInfo.getCreatedOn());
        gspBeExtendInfoEntity.setLastChangedBy(gspBeExtendInfo.getLastChangedBy());
        gspBeExtendInfoEntity.setLastChangedOn(gspBeExtendInfo.getLastChangedOn());
        gspBeExtendInfoEntity.setExtendInfo(gspBeExtendInfo.getExtendInfo());
        gspBeExtendInfoEntity.setBeConfigCollectionInfo(Json.pretty(gspBeExtendInfo.getBeConfigCollectionInfo()));
        return gspBeExtendInfoEntity;
    }


    private BeConfigCollectionInfo convertToBeConfigCollectionInfo(String dbData) {
        if (dbData == null || dbData.isEmpty()) {
            return new BeConfigCollectionInfo();
        }
        BeConfigCollectionInfo configCollectionInfo = null;
        try {
            configCollectionInfo = JsonUtil.toObject(dbData, BeConfigCollectionInfo.class);
        } catch (JsonUtil.JsonParseException e) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0001, e, "BeConfigCollectionInfo");
        }
        return configCollectionInfo;
    }

    @Override
    public GspBeExtendInfo getBeExtendInfoByConfigId(String configId) {
        if (configId == null || configId.length() == 0)
            return null;
        GspBeExtendInfo gspBeExtendInfoFromCache = gspBeExtendInfoCacheManager.get(configId);
        if (gspBeExtendInfoFromCache != null) {
            return gspBeExtendInfoFromCache;
        }
        List<GspBeExtendInfoEntity> infos = repository.getBeExtendInfosByConfigId(configId);
        if (infos.size() > 1) {
            StringBuilder exceptionInfo = new StringBuilder("存在重复configID: [" + configId + "],请处理数据库中的异常重复数据。");
            int index = 1;
            for (GspBeExtendInfoEntity info : infos) {
                exceptionInfo.append("\n重复元数据[").append(index).append("]的Id为：[").append(info.getId()).append("]");
                index++;
            }
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_TEMPLATE_ERROR, exceptionInfo.toString());
        } else if (infos.size() == 0) {
            return null;
        } else {
            GspBeExtendInfo beExtendInfoFromRepo = getGspBeExtendInfo(infos.get(0));
            gspBeExtendInfoCacheManager.put(configId, beExtendInfoFromRepo);
            return beExtendInfoFromRepo;
        }
    }

    @Override
    public List<GspBeExtendInfo> getBeExtendInfos() {
        List<GspBeExtendInfo> gspBeExtendInfos = new ArrayList<>();
        List<GspBeExtendInfoEntity> gspBeExtendInfoEntities = repository.findAll();
        if (gspBeExtendInfoEntities == null || gspBeExtendInfoEntities.isEmpty())
            return gspBeExtendInfos;
        for (GspBeExtendInfoEntity entity : gspBeExtendInfoEntities) {
            GspBeExtendInfo gspBeExtendInfo = getGspBeExtendInfo(entity);
            gspBeExtendInfos.add(gspBeExtendInfo);
        }
        return gspBeExtendInfos;
    }

    @Override
    public void saveGspBeExtendInfos(List<GspBeExtendInfo> infos) {
        if (infos == null || infos.isEmpty())
            return;
        List<GspBeExtendInfoEntity> gspBeExtendInfoEntities = new ArrayList<>(infos.size());
        for (GspBeExtendInfo info : infos) {
            if (info == null)
                continue;
            GspBeExtendInfoEntity entity = getGspBeExtendInfoEntity(info);
            gspBeExtendInfoEntities.add(entity);
        }
        repository.saveAll(gspBeExtendInfoEntities);
    }

    @Override
    public void deleteBeExtendInfo(String id) {
        GspBeExtendInfoEntity beExtendInfoEntity = repository.findById(id).orElse(null);
        GspBeExtendInfo beExtendInfo = getGspBeExtendInfo(beExtendInfoEntity);
        if (beExtendInfo != null) {
            repository.deleteById(id);
            gspBeExtendInfoCacheManager.delete(id);
        }
        if (beExtendInfo != null && beExtendInfo.getConfigId() != null) {
            gspBeExtendInfoCacheManager.delete(beExtendInfo.getConfigId());
        }
    }
}
